package api

import (
	"strconv"

	"github.com/gin-gonic/gin"

	articleApp "BookStack/internal/application/article"
	"BookStack/internal/domain/article"
	"BookStack/internal/interfaces/middleware"
	"BookStack/internal/interfaces/presenter"
)

// ArticleHandler 文章API处理器
type ArticleHandler struct {
	articleService articleApp.Service
	response       presenter.ResponseFormatter
}

// NewArticleHandler 创建文章API处理器
func NewArticleHandler(articleService articleApp.Service) *ArticleHandler {
	return &ArticleHandler{
		articleService: articleService,
		response:       presenter.NewResponseFormatter(),
	}
}

// RegisterRoutes 注册文章相关路由
func (h *ArticleHandler) RegisterRoutes(router *gin.RouterGroup) {
	// 公开API
	router.GET("/article", h.ListArticles)
	router.GET("/article/:id", h.GetArticleByID)
	router.GET("/article/slug/:slug", h.GetArticleBySlug)
	router.GET("/article/category/:id", h.ListArticlesByCategory)
	router.GET("/article/recommended", h.ListRecommendedArticles)
	router.POST("/article/:id/like", h.LikeArticle)
	router.DELETE("/article/:id/like", h.UnlikeArticle)

	// 需要认证的API
	authRouter := router.Group("/article")
	authRouter.Use(middleware.JWTAuth()) // 认证中间件
	{
		authRouter.GET("/my", h.ListMyArticles)
	}

	// 管理员API
	adminRouter := router.Group("/admin/article")
	adminRouter.Use(middleware.JWTAuth(), middleware.AdminAuth()) // 管理员权限认证中间件
	{
		adminRouter.POST("", h.CreateArticle)
		adminRouter.PUT("", h.UpdateArticle)
		adminRouter.DELETE("/:id", h.DeleteArticle)
		adminRouter.PUT("/status", h.SetArticleStatus)
		adminRouter.PUT("/recommend", h.SetArticleRecommend)
		adminRouter.PUT("/:id/publish", h.PublishArticle)
		adminRouter.PUT("/:id/archive", h.ArchiveArticle)
		adminRouter.PUT("/:id/draft", h.DraftArticle)
	}
}

// ListArticles 获取文章列表
func (h *ArticleHandler) ListArticles(c *gin.Context) {
	page, pageSize := getPagination(c)
	filters := map[string]interface{}{
		"status": article.StatusPublished, // 默认只显示已发布的文章
	}

	resp, err := h.articleService.List(c, page, pageSize, filters)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, resp)
}

// GetArticleByID 根据ID获取文章详情
func (h *ArticleHandler) GetArticleByID(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(articleApp.ValidationFailed(map[string]string{"id": "无效的文章ID"}))
		return
	}

	article, err := h.articleService.GetByID(c, uint(id))
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, article)
}

// GetArticleBySlug 根据Slug获取文章详情
func (h *ArticleHandler) GetArticleBySlug(c *gin.Context) {
	slug := c.Param("slug")
	if slug == "" {
		c.Error(articleApp.ValidationFailed(map[string]string{"slug": "无效的文章Slug"}))
		return
	}

	article, err := h.articleService.GetBySlug(c, slug)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, article)
}

// ListArticlesByCategory 获取分类下的文章列表
func (h *ArticleHandler) ListArticlesByCategory(c *gin.Context) {
	page, pageSize := getPagination(c)
	categoryID, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(articleApp.ValidationFailed(map[string]string{"category_id": "无效的分类ID"}))
		return
	}

	resp, err := h.articleService.ListByCategory(c, uint(categoryID), page, pageSize)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, resp)
}

// ListRecommendedArticles 获取推荐文章列表
func (h *ArticleHandler) ListRecommendedArticles(c *gin.Context) {
	page, pageSize := getPagination(c)

	resp, err := h.articleService.ListRecommended(c, page, pageSize)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, resp)
}

// CreateArticle 创建文章
func (h *ArticleHandler) CreateArticle(c *gin.Context) {
	var req articleApp.CreateArticleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		// 将解析错误直接传递给错误中间件处理
		c.Error(err)
		return
	}

	userID := getUserIDFromContext(c)
	article, err := h.articleService.Create(c, &req, userID)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Created(c, article)
}

// UpdateArticle 更新文章
func (h *ArticleHandler) UpdateArticle(c *gin.Context) {
	var req articleApp.UpdateArticleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		// 将解析错误直接传递给错误中间件处理
		c.Error(err)
		return
	}

	userID := getUserIDFromContext(c)
	article, err := h.articleService.Update(c, &req, userID)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, article)
}

// DeleteArticle 删除文章
func (h *ArticleHandler) DeleteArticle(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(articleApp.ValidationFailed(map[string]string{"id": "无效的文章ID"}))
		return
	}

	if err := h.articleService.Delete(c, uint(id)); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// ListMyArticles 获取当前用户的文章列表
func (h *ArticleHandler) ListMyArticles(c *gin.Context) {
	page, pageSize := getPagination(c)
	userID := getUserIDFromContext(c)

	resp, err := h.articleService.ListByAuthor(c, userID, page, pageSize)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, resp)
}

// LikeArticle 点赞文章
func (h *ArticleHandler) LikeArticle(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(articleApp.ValidationFailed(map[string]string{"id": "无效的文章ID"}))
		return
	}

	if err := h.articleService.IncrementLikes(c, uint(id)); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// UnlikeArticle 取消点赞
func (h *ArticleHandler) UnlikeArticle(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(articleApp.ValidationFailed(map[string]string{"id": "无效的文章ID"}))
		return
	}

	if err := h.articleService.DecrementLikes(c, uint(id)); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// SetArticleStatus 设置文章状态
func (h *ArticleHandler) SetArticleStatus(c *gin.Context) {
	var req articleApp.SetStatusRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		// 将解析错误直接传递给错误中间件处理
		c.Error(err)
		return
	}

	if err := h.articleService.SetStatus(c, &req); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// SetArticleRecommend 设置文章推荐状态
func (h *ArticleHandler) SetArticleRecommend(c *gin.Context) {
	var req articleApp.SetRecommendRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		// 将解析错误直接传递给错误中间件处理
		c.Error(err)
		return
	}

	if err := h.articleService.SetRecommend(c, &req); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// PublishArticle 发布文章
func (h *ArticleHandler) PublishArticle(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(articleApp.ValidationFailed(map[string]string{"id": "无效的文章ID"}))
		return
	}

	if err := h.articleService.Publish(c, uint(id)); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// ArchiveArticle 归档文章
func (h *ArticleHandler) ArchiveArticle(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(articleApp.ValidationFailed(map[string]string{"id": "无效的文章ID"}))
		return
	}

	if err := h.articleService.Archive(c, uint(id)); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// DraftArticle 设置文章为草稿
func (h *ArticleHandler) DraftArticle(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(articleApp.ValidationFailed(map[string]string{"id": "无效的文章ID"}))
		return
	}

	if err := h.articleService.Draft(c, uint(id)); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// getPagination 获取分页参数
func getPagination(c *gin.Context) (page, pageSize int) {
	page, _ = strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ = strconv.Atoi(c.DefaultQuery("page_size", "10"))

	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 || pageSize > 100 {
		pageSize = 10
	}

	return page, pageSize
}

// getUserIDFromContext 从上下文中获取用户ID
func getUserIDFromContext(c *gin.Context) uint {
	userID, exists := c.Get("user_id")
	if !exists {
		return 0
	}
	uid, ok := userID.(uint)
	if !ok {
		return 0
	}
	return uid
}
